-----------Word Attack Plus!-----------
A 4am crack                  2017-06-30
---------------------------------------

Name: Word Attack Plus!
Version: 1.2
Genre: educational
Year: 1988
Credits: designed by Jan Davidson,
  Julie Baumgartner, and J.M. Albanese;
  written by Kevin R. Burley
Publisher: Davidson & Associates, Inc.
Media: one double-sided 5.25-inch disk
OS: ProDOS 1.4
Previous cracks: none (of this version)
Identical cracks:
  #200 Math Blaster Mystery
  #219 Word Attack Plus! Spanish

Only side A is bootable, so I'll start
there.

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  disk read error on last pass

Locksmith Fast Disk Backup
  read error on T22,S00; copy boots to
  ProDOS then quits to program selector

EDD 4 bit copy (no sync, no count)
  works

Copy ][+ nibble editor
  T22,S00 exists with standard address
  and data fields, so no obvious reason
  why it shouldn't be readable

Disk Fixer
  After ignoring checksums, I can read
  T22,S00. The prologues and epilogues
  are standard, so maybe it's literally
  a bad checksum.

Why didn't COPYA work?
  intentionally bad sector on T22

Why didn't Locksmith FDB work?
  Probably a nibble check in the first
  SYSTEM file that reads the unreadable
  sector on T22

                   ~

               Chapter 1
        In Which We Meditate On
       The Definition Of Success


[S6,D1=original disk]
[S7,D1=ProDOS hard drive]

]PR#7
]CAT,S6,D1

/WORD

 NAME           TYPE  BLOCKS  MODIFIED

 AFORTH          BIN      43  20-SEP-88
 WAP.SYSTEM      SYS       4  20-SEP-88
 TK.ABS          BIN      28  20-SEP-88
 PRODOS          SYS      32  20-SEP-88
 G13.OVL         TXT      25  21-SEP-88
 G4.OVL          TXT       7  21-SEP-88
 G5.OVL          TXT      13  21-SEP-88
 ED.OVL          TXT      22  21-SEP-88
 PRINT.OVL       TXT      11  21-SEP-88
 GAME.STR.OBJ    TXT      10  21-SEP-88
 ED.STR.OBJ      TXT       7  21-SEP-88
 PRINT.STR.OBJ   TXT       1  21-SEP-88
 IMAGE.OBJ       TXT      15  20-SEP-88
 ENTRY.PAK       TXT       7  20-SEP-88
 MAIN.PAK        TXT      10  20-SEP-88
 CERT.PAK        TXT       9  20-SEP-88
 FOREIGN.FONT.3  BIN       7  20-SEP-88
 PRINTER.DATA    TXT       1  20-SEP-88
 PRINTER.DRIVERS TXT      12  20-SEP-88
 INTER.DRIVERS   TXT       5  20-SEP-88
 DUMP.HIRES.R    BIN       5  20-SEP-88

BLOCKS FREE:    0     BLOCKS USED:  280

ProDOS always loads the first .SYSTEM
file at $2000 and jumps to it.

]PREFIX /WORD
]BLOAD WAP.SYSTEM,A$2000,TSYS
]CALL -151

*2000L

2000-   20 D2 25    JSR   $25D2
2003-   4C 74 08    JMP   $0874

There's nothing loaded at $0874 yet, so
the subroutine at $25D2 must load
something from disk or copy something
from memory.

*25D2L

; straightforward memory relocation
25D2-   A2 00       LDX   #$00
25D4-   BD 03 20    LDA   $2003,X
25D7-   9D 01 08    STA   $0801,X
25DA-   BD 03 21    LDA   $2103,X
25DD-   9D 01 09    STA   $0901,X
25E0-   BD 03 22    LDA   $2203,X
25E3-   9D 01 0A    STA   $0A01,X
25E6-   BD 03 23    LDA   $2303,X
25E9-   9D 01 0B    STA   $0B01,X
25EC-   BD 03 24    LDA   $2403,X
25EF-   9D 01 0C    STA   $0C01,X
25F2-   BD 03 25    LDA   $2503,X
25F5-   E8          INX
25F6-   D0 DC       BNE   $25D4
25F8-   60          RTS

That's harmless enough. Let's run it.

*25D2G

*874L

0874-   20 C8 0A    JSR   $0AC8
0877-   F0 D9       BEQ   $0852

Down the rabbit hole we go.

*AC8L

; $BF30 is the last used slot and drive
; in "DSSS0000" format ("Beneath Apple
; ProDOS", p. 8-6)
0AC8-   AD 30 BF    LDA   $BF30
0ACB-   4A          LSR
0ACC-   4A          LSR
0ACD-   4A          LSR
0ACE-   4A          LSR
0ACF-   29 07       AND   #$07
0AD1-   09 C0       ORA   #$C0

; slot number munged into the high byte
; of the drive slot ROM, e.g. $C6
0AD3-   85 61       STA   $61
0AD5-   A9 00       LDA   #$00
0AD7-   85 60       STA   $60

; standard fingerprinting to identify
; the drive ROM
0AD9-   A0 01       LDY   #$01
0ADB-   B1 60       LDA   ($60),Y
0ADD-   C9 20       CMP   #$20
0ADF-   D0 22       BNE   $0B03
0AE1-   A0 03       LDY   #$03
0AE3-   B1 60       LDA   ($60),Y
0AE5-   D0 1C       BNE   $0B03
0AE7-   A0 05       LDY   #$05
0AE9-   B1 60       LDA   ($60),Y
0AEB-   C9 03       CMP   #$03
0AED-   D0 14       BNE   $0B03
0AEF-   A0 FF       LDY   #$FF
0AF1-   B1 60       LDA   ($60),Y
0AF3-   D0 0E       BNE   $0B03

; 5.25-inch floppy drive, so check
; block $110 (includes T22,S00)
0AF5-   A9 10       LDA   #$10
0AF7-   8D CE 0D    STA   $0DCE
0AFA-   A9 01       LDA   #$01
0AFC-   8D CF 0D    STA   $0DCF
0AFF-   D0 0C       BNE   $0B0D
0B01-   F0 0A       BEQ   $0B0D

; 3.5-inch floppy drive, so check
; block $308
0B03-   A9 08       LDA   #$08
0B05-   8D CE 0D    STA   $0DCE
0B08-   A9 03       LDA   #$03
0B0A-   8D CF 0D    STA   $0DCF

; set up other MLI parameters
0B0D-   AD 30 BF    LDA   $BF30
0B10-   8D CB 0D    STA   $0DCB
0B13-   A9 03       LDA   #$03
0B15-   8D CA 0D    STA   $0DCA
0B18-   A9 CA       LDA   #$CA
0B1A-   8D CC 0D    STA   $0DCC
0B1D-   A9 0B       LDA   #$0B
0B1F-   8D CD 0D    STA   $0DCD

; call MLI to read the specified block
; from disk (the $80 byte following the
; JSR is the READ_BLOCK command, and
; following that is the address of the
; MLI parameter table, $0DCA)
0B22-   20 00 BF    JSR   $BF00
0B25-  [80 CA 0D]

; if there was NOT a disk read error,
; then branch
0B28-   90 09       BCC   $0B33

; if there was any error other than an
; I/O error ($27), then branch
0B2A-   C9 27       CMP   #$27
0B2C-   D0 05       BNE   $0B33

; success path is here
0B2E-   A9 FF       LDA   #$FF
0B30-   85 FF       STA   $FF
0B32-   60          RTS

; failure path is here
0B33-   A9 00       LDA   #$00
0B35-   85 FF       STA   $FF
0B37-   60          RTS

This isn't a nibble check, per se. But
it is definitely a form of copy
protection. (Fun fact: it appears to be
written so it can be re-used for 5.25-
and 3.5-inch floppies.) It relies on
one specific sector being unreadable,
and fails if it's actually readable.
Since Locksmith FDB just wrote a zeroed
(but standard) sector to T22,S00, the
MLI read routine unexpectedly succeeds,
and the program knows it's been copied.

Returning to the caller:

0874-   20 C8 0A    JSR   $0AC8
0877-   F0 D9       BEQ   $0852

*852L

; read and write main memory
0852-   8E 04 C0    STX   $C004
0855-   8E 02 C0    STX   $C002

; call the quit handler (command $65)
0858-   20 00 BF    JSR   $BF00
085B-  [65 5E 08]

...which explains the behavior I saw on
my non-working copy.

Let's reproduce the success path. I'm
not sure if the side effect of setting
zero page $FF is relevant, but let's
assume it is.

*FF:FF N 879G

The program loads without complaint.

Out of curiosity, I reproduced this
state and tried it with $FF=0.

*FF:00 N 879G

It still loads without complaint.

Popping the stack all the way back to
$2003, I can change JMP $0874 to $0879
and bypass the entire thing.

T06,S00,$04: 74 -> 79

]PR#6
...works...

Side B is unprotected.

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1286
------------------EOF------------------
